#ifndef DISPENSEWORKHOLDER_H
#define DISPENSEWORKHOLDER_H

#include "AxisModule/singleaxis.h"
#include "BasicElement/scaxis.h"
#include "CompositeElement/sccylinder.h"
#include "CompositeElement/scvacuum.h"
#include "MotionManager/motionelementcontainer.h"
#include "Tray/sensortraymaterialdata.h"
#include "Tray/trayconfig.h"
#include "Tray/traymap.h"
#include "dispensehead.h"
#include "dispenseworkholderconfig.h"
#include "namedefinition.h"
#include "systemCore/worker.h"
#include "workers/SensorTrayElevator/sensortrayinputelevator.h"
#include "workers/workholderstate.h"

class DispenseWorkHolder : public Worker
{
    Q_OBJECT
public:
    DispenseWorkHolder(TrayConfig *sensorTrayConfig,
                       TrayMap *sensorTrayMap,
                       WorkHolderState *whState,
                       DispenseHead *leftDH,
                       DispenseHead *rightDH,
                       SensorTrayInputElevator *stie,
                       QObject *parent = nullptr);

    DispWHConfig *getDispWHConfig() const;
    TrayMap *getTrayMap() const;

    // Worker interface
protected:
    virtual void initEventHandle() override;
    virtual void startEventHandle(const WorkerEvent &event) override;
    virtual void stopEventHandle() override;
    virtual void allWorkerStopped() override;
    virtual void purgeEventHandle() override;
    virtual void resetEventHandle() override;
    virtual void homeWorker(bool moveToReadyPosAfterHome) override;

    // 自动运行逻辑
public slots:
    void getNewTray();
    void pushOutTray();
    void hasDoneWork();

    // 手动调试操作
public slots:
    void manuallyGetNewTray(bool showTip = true);
    void returnBackTray();
    void manuallyPushOutTray();

private:
    void upBeltZ();
    void downBeltZ();
    void getNewTrayImpl();
    void pushOutTrayImpl();
    void synchronizeHasTray();
    bool detectReallyHasTray();
    void makeSureEntranceHasNotTray();
    void handleStop();

private:
    ConfigFile *configFile;
    DispWHConfig *dispWHConfig;

    TrayConfig *sensorTrayConfig;
    TrayMap *sensorTrayMap;
    WorkHolderState *whState;

    DispenseHead *leftDH;
    DispenseHead *rightDH;

    SensorTrayInputElevator *stie = nullptr;

    // dispWH: dispense work holder
    SingleAxis *dispWHBeltZModule;
    SCAxis *dispWHBelt;
    SCVacuum *dispWHVacuum;
    SCCylinder *dispWHStopperCyl;
    SCDI *dispWHLeftTraySensor;
    SCDI *dispWHStageTraySensor;

    SCAxis::Direction beltRunDir;

    bool hasSynchronizeHasTray = false;
    bool isStopping = false;
};

#endif    // DISPENSEWORKHOLDER_H
